<!--
 * Copyright ©
 * #  
 * @author: zw
 * @date: 2023-03-05 
 -->


<template>
  <div class="g6-component-contextmenu" v-clickoutside="onMenuHide">
    <ul class="g6-contextmenu-ul">
      <li v-for="item, index in list" :key="index" @click="handleMenuClick(item)">{{ item.label }}</li>
    </ul>
  </div>
</template>

<script>
import Clickoutside from 'element-ui/src/utils/clickoutside';

export default {
  name: 'contextmenu',
  directives: { Clickoutside },

  data() {
    return {
      itemNode: null,
      list: [
        { label: '删除', code: 'del', },
        { label: '克隆', code: 'clone', },
        { label: '属性面板', code: 'edit', },
      ]
    };
  },
  props: {
    graph: { type: Object, required: true },
    offsetX: { type: Number, default: 0 },
    offsetY: { type: Number, default: 0 },
    itemTypes: { type: Array, default: () => ['node', 'edge', 'combo'] },
  },

  mounted() { },

  methods: {
    handleMenuClick(item) {
      const { code } = item;
      const { graph, itemNode } = this;
      switch (code) {

        case 'del':
          graph.removeItem(itemNode);
          break;

        case 'clone':
          const { id, x, y } = itemNode.getModel();
          const cloneNode = {
            ...itemNode.getModel(),
            id: `clone-${Math.random().toString().slice(3, 6)}`,
            x: x + 20,
            y: y + 20,
          };
          graph.addItem('node', cloneNode);
          break;

        case 'edit':
          itemNode.toFront();
          const bool = itemNode.hasState('selected');
          itemNode.setState('selected', !bool);
          graph.emit('node-click', { item: itemNode, model: itemNode.getModel() });

        default:
          break;

      }
      this.onMenuHide();

    },
    onMenuShow(e) {
      e.preventDefault();
      const { graph, itemTypes, offsetX, offsetY } = this;
      if (!e.item) {
        if (itemTypes.indexOf('canvas') === -1) return this.onMenuHide();
      } else {
        if (e.item && e.item.getType && itemTypes.indexOf(e.item.getType()) === -1) return this.onMenuHide();
      }

      this.itemNode = e.item;
      const width = graph.get('width');
      const height = graph.get('height');
      const bbox = this.$el.getBoundingClientRect();
      const graphTop = graph.getContainer().offsetTop;
      const graphLeft = graph.getContainer().offsetLeft;
      let x = e.canvasX + graphLeft + offsetX;
      let y = e.canvasY + graphTop + offsetY;

      if (x + bbox.width > width) x = e.canvasX - bbox.width - offsetX + graphLeft;// 当菜单(部分)脱离画布时
      if (y + bbox.height > height) y = e.canvasY - bbox.height - offsetY + graphTop;

      this.$el.style.left = `${x}px`;
      this.$el.style.top = `${y}px`;
      this.$el.style.visibility = 'visible';



    },
    onMenuHide() {
      this.$el.style.visibility = 'hidden';
    },
  }
  //  End
}

</script>

<style lang='scss' scoped>
.g6-component-contextmenu {
  position: absolute;
  visibility: hidden;
  padding: 5px 0;
  margin: 0;
  font-size: 14px;
  color: #606266;
  font-weight: 400;
  display: inline-block;
  box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.5);
  border: 1px solid #ebeef5;
  border-radius: 2px;
  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
    Microsoft YaHei, SimSun, sans-serif;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

.g6-component-contextmenu ul.g6-contextmenu-ul {
  list-style: none;
  padding: 0;
  margin: 0;
  background-color: #fff;
}

.g6-component-contextmenu ul li {
  text-indent: 1em;
  height: 24px;
  width: 100px;
  line-height: 24px;
  padding: 0;
  cursor: pointer;
  position: relative;
  box-sizing: content-box;
}

.g6-component-contextmenu ul li::after {
  content: "";
  position: absolute;
  top: 90%;
  left: 5%;
  width: 90%;
  height: 1px;
  background-color: #ebeef5;
  z-index: 1;
}

.g6-component-contextmenu ul li:last-child::after {
  background-color: unset;
}

.g6-component-contextmenu ul li:hover {
  background-color: #e8e8e9;
}
</style>
